<template>
  <div class="container">
      <!-- 商品分类面包屑导航 -->
      <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>商品管理</el-breadcrumb-item>
        <el-breadcrumb-item>商品分类</el-breadcrumb-item>
      </el-breadcrumb>
      <!-- 卡片区域 -->
      <el-card class="box-card">
        <!-- 添加商品分类 -->
        <el-button type="primary" round @click="addCategoryFormOpen">新增商品分类</el-button>
        <!-- vue-table-with-tree-grid表格树形展示区 -->
        <tree-table
        :data="categoryList"
        :columns="columsSet"
        tree-type
        :show-row-hover="false"
        :expand-type="false"
        show-index
        index="center"
        border
        :selection-type="false"
        >
          <!-- 是否有效使用图标表示 -->
          <template slot="isTrue" slot-scope="scope">
              <el-button class="btn-width" type="success" v-if="!scope.row.cat_deleted" icon="el-icon-check" circle></el-button>
              <el-button class="btn-width" type="danger" v-else icon="el-icon-close" circle></el-button>
          </template>
          <!-- 分类等级使用Tag标签展示 -->
          <template slot="levelTag" slot-scope="scope">
              <el-tag type="danger" v-if="scope.row.cat_level == 0" effect="plain">所属一级分类</el-tag>
              <el-tag type="" v-else-if="scope.row.cat_level == 1" effect="plain">所属二级分类</el-tag>
              <el-tag type="success" v-else effect="plain">商品三级分类</el-tag>
          </template>
          <!-- 树形列表操作列 编辑—删除 按钮 -->
          <template slot="operation" slot-scope="scope">
            <el-button class="margin-r" type="primary" icon="el-icon-edit" size="mini" @click="editCategoryName(scope.row)">编辑</el-button>
            <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeCategory(scope.row)">删除</el-button>
          </template>
        </tree-table>
        <!-- 分页器区域 -->
        <template>
          <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="categoryPageShow.pagenum"
            :page-sizes="[5, 10, 15, 20]"
            :page-size="categoryPageShow.pagesize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="categoryTotal">
          </el-pagination>
        </template>
      </el-card>
      <!-- 新增商品分类弹出框 -->
      <el-dialog title="新增商品分类" :visible.sync="addCategoryFormBool" @close="addCategoryFormClose">
        <el-form :model="addCategoryFormInfo" status-icon ref="addCategoryFormRef" :rules="addCategoryFormRules" label-position="right"  label-width="130px">
          <el-form-item label="新商品分类名称" label-width="130px" prop="cat_name">
            <el-input autocomplete placeholder="请输入新增的商品分类名称..." v-model="addCategoryFormInfo.cat_name"></el-input>
          </el-form-item>
          <el-form-item label="新分类所属父级" label-width="130px">
            <div class="block">
              <el-cascader
                placeholder="选择新增分类所属父级，不填则新增商品一级分类..."
                v-model="selectNum"
                :options="categoryData"
                :props="categoryOptions"
                clearable></el-cascader>
            </div>
          </el-form-item>
        </el-form>
        <el-row slot="footer">
          <el-col :span="14">
            <el-alert
              title="新增商品分类说明"
              type="info"
              :closable="false"
              description
              show-icon>
              <template slot="">
                <p>所属父级为空，则默认新增商品一级分类名称</p>
                <p>所属父级为一级分类，则新增分类归属其下二级分类</p>
                <p>所属父级为二级分类，则新增分类归属其下三级分类</p>
              </template>
            </el-alert>
          </el-col>
          <el-col :span="10">
            <div class="dialog-footer">
              <el-button @click="addCategoryFormBool = false">取 消</el-button>
              <el-button type="primary" @click="addCategoryFormSubmit">确 定</el-button>
            </div>
          </el-col>
        </el-row>
      </el-dialog>
      <!-- 编辑商品分类弹出框 -->
      <el-dialog :title="`正在编辑分类名称 【${editCategoryFormInfo.cat_name}】`" :visible.sync="editCategoryFormBool" @close="editCategoryFormClose">
        <el-form :model="currentCategory" status-icon ref="editCategoryFormRef" :rules="editCategoryFormRules" label-position="right"  label-width="140px">
          <el-form-item label="修改商品分类名称" label-width="140px" prop="cat_name">
            <el-input autocomplete :placeholder="`正在修改 ${editCategoryFormInfo.cat_name} 商品分类名称...`" v-model="currentCategory.cat_name"></el-input>
          </el-form-item>
        </el-form>
        <div slot="footer">
          <el-button @click="editCategoryFormBool = false">取 消</el-button>
          <el-button type="primary" @click="editCategoryFormSubmit">确 定</el-button>
        </div>
      </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'Category',
  created () {
    this.getCategoriesList()
  },
  data () {
    // 分类名自定义验证规则，验证是否已存在
    var categoryNameRepeat = async (rule, value, callback) => {
      // 第一次请求获取商品一级分类名
      const { data: resF } = await this.$http.get('categories', { params: { type: 1 } })
      // 第二次请求获取商品二级分类名
      const { data: resS } = await this.$http.get('categories', { params: { type: 2 } })
      if (resF.meta.status !== 200 || resS.meta.status !== 200) return callback(new Error('分类数据异常'))
      const categoryDataF = resF.data
      const categoryDataS = resS.data
      const oldCategoryName = []
      allCategoryName(categoryDataF, oldCategoryName)
      allCategoryName(categoryDataS, oldCategoryName)
      if (oldCategoryName.indexOf(value) !== -1) return callback(new Error('该父级分类名已经存在，请查找添加其子级分类！'))
      callback()
    }
    // 修改分类名自定义验证规则-------------------------------------------------------------------
    var editCategoryName = async (rule, value, callback, level, oldvalue) => {
      // 判断分类名是否改变
      if (value === oldvalue) return callback(new Error('您没有对分类名称进行修改，请取消或尝试修改后再进行提交！'))
      // 请求当前层级所有分类名称
      const { data: res } = await this.$http.get('categories', { params: level + 1 })
      if (res.meta.status !== 200) return callback(new Error('数据库异常，请稍后重试修改操作！'))
      const serverCategoryData = res.data
      const serverAllCategoryName = []
      serverCategoryData.forEach(item => {
        serverAllCategoryName.push(item.cat_name)
      })
      let levelName = ''
      switch (level) {
        case 0:
          levelName = '商品一级分类'
          break
        case 1:
          levelName = '商品二级分类'
          break
        default:
          levelName = '商品三级分类'
          break
      }
      if (serverAllCategoryName.indexOf(value) !== -1) return callback(new Error(`当前 ${levelName} 已经存在该 ${value} 分类名称，请查找或更换后尝试！`))
      callback()
    }

    // 递归获取所有一二层分类名
    function allCategoryName (categoryTree, newArr) {
      categoryTree.forEach(item => {
        if (!item.children) return newArr.push(item.cat_name)
        allCategoryName(item.children, newArr)
      })
    }
    return {
      // 商品分类列表
      categoryList: [],
      // 表格树列配置项
      columsSet: [
        { label: '商品分类结构', prop: 'cat_name', headerAlign: 'center', align: 'left' },
        { label: '商品分类状态', prop: 'cat_deleted', type: 'template', headerAlign: 'center', template: 'isTrue', width: '100px', align: 'center' },
        { label: '商品分类层级', prop: 'cat_level', type: 'template', headerAlign: 'center', template: 'levelTag', align: 'center' },
        { label: '商品分类操作', type: 'template', headerAlign: 'center', template: 'operation', width: '250px', align: 'center' }
      ],
      // 商品分类数据列表分页数据
      categoryPageShow: {
        type: '',
        pagenum: 1,
        pagesize: 5
      },
      // 数据总条数
      categoryTotal: 0,
      // 新增商品分类弹出框
      addCategoryFormBool: false,
      // 新增商品分类信息
      addCategoryFormInfo: {
        cat_pid: 0,
        cat_name: '',
        cat_level: 0
      },
      // 新增商品分类名称校验规则
      addCategoryFormRules: {
        cat_name: [
          { required: true, message: '商品分类名称必须填写...', trigger: 'blur' },
          { max: 10, message: '分类名称不能超过10个字符，请归纳精简...', trigger: 'blur' },
          { validator: categoryNameRepeat, trigger: 'blur' }
        ]
      },
      // 修改商品分类名称校验规则---------------------------------------------------------------------------
      editCategoryFormRules: {
        cat_name: [
          { required: true, message: '商品分类名称不允许修改为空...', trigger: 'blur' },
          { max: 10, message: '分类名称不能超过10个字符，请归纳精简...', trigger: 'blur' },
          { validator: (rule, value, callback) => { editCategoryName(rule, value, callback, this.currentCategory.cat_level, this.editCategoryFormInfo.cat_name) }, trigger: 'blur' }
        ]
      },
      // 级联选择器分类数据源
      categoryData: [],
      // 级联选择器配置项
      categoryOptions: {
        checkStrictly: true,
        expandTrigger: 'hover',
        label: 'cat_name',
        value: 'cat_id'
      },
      // 级联选择器选中项
      selectNum: [],
      // 修改商品分类弹出框
      editCategoryFormBool: false,
      // 当前修改商品分类信息
      editCategoryFormInfo: {},
      // 当前操作分类信息名称
      currentCategory: {
        cat_level: '',
        cat_id: '',
        cat_name: ''
      }
    }
  },
  methods: {
    // 获取分类商品初始化数据
    async getCategoriesList () {
      const { data: res } = await this.$http.get('categories', { params: this.categoryPageShow })
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.categoryList = res.data.result
      this.categoryTotal = res.data.total
    },
    // element-ui分页内置监听页码范围变化
    handleSizeChange (pageSize) {
      this.categoryPageShow.pagesize = pageSize
      this.getCategoriesList()
    },
    // element-ui分页内置监听当前页变化
    handleCurrentChange (currentPage) {
      this.categoryPageShow.pagenum = currentPage
      this.getCategoriesList()
    },
    // 打开新增商品分类对话框
    addCategoryFormOpen () {
      this.addCategoryFormBool = true
      this.getCategoryCascaData()
    },
    // 关闭新增商品分类对话框
    addCategoryFormClose () {
      this.$refs.addCategoryFormRef.resetFields()
      this.selectNum = []
    },
    // 新增商品分类提交请求
    addCategoryFormSubmit () {
      this.addCategoryFormInfo.cat_level = this.selectNum.length
      this.addCategoryFormInfo.cat_pid = this.selectNum.length !== 0 ? this.selectNum[this.selectNum.length - 1] : 0
      this.$refs.addCategoryFormRef.validate(async valid => {
        if (!valid) return this.$message.error('商品分类名称信息不合法，请检查...')
        this.addCategoryFormBool = false
        const { data: res } = await this.$http.post('categories', this.addCategoryFormInfo)
        if (res.meta.status !== 201) return this.$message.error(res.meta.msg)
        this.getCategoriesList()
        this.$message.success(res.meta.msg)
      })
    },
    // 获取商品分类一、二层数据
    async getCategoryCascaData () {
      const { data: res } = await this.$http.get('categories', { params: { type: 2 } })
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.categoryData = res.data
    },
    // 编辑当前商品分类名称
    editCategoryName (categoryInfo) {
      this.editCategoryFormInfo = categoryInfo
      this.currentCategory.cat_id = categoryInfo.cat_id
      this.currentCategory.cat_name = categoryInfo.cat_name
      this.currentCategory.cat_level = categoryInfo.cat_level
      this.editCategoryFormBool = true
    },
    // 关闭当前商品分类
    editCategoryFormClose () {
      this.$refs.editCategoryFormRef.resetFields()
    },
    // 编辑商品分类提交
    editCategoryFormSubmit () {
      this.$refs.editCategoryFormRef.validate(async valid => {
        if (!valid) return this.$message.error('分类名称已存在，或存在不合法信息，请检查！')
        const { data: res } = await this.$http.put(`categories/${this.currentCategory.cat_id}`, { cat_name: this.currentCategory.cat_name })
        if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
        this.$message.success(res.meta.msg)
        this.getCategoriesList()
        this.editCategoryFormBool = false
      })
    },
    // 删除当前商品分类
    async removeCategory (categoryInfo) {
      let levelName = ''
      switch (categoryInfo.cat_level) {
        case 0:
          levelName = '一级分类'
          break
        case 1:
          levelName = '二级分类'
          break
        default:
          levelName = '三级分类'
          break
      }
      const confirmRes = await this.$confirm(`确定要删除所属${levelName}的 【${categoryInfo.cat_name}】 分类名称?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      if (confirmRes !== 'confirm') return this.$message.info(`所属${levelName}的 【${categoryInfo.cat_name}】 分类名称删除操作被终止！`)
      const { data: res } = await this.$http.delete(`categories/${categoryInfo.cat_id}`)
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.getCategoriesList()
      this.$message.success(res.meta.msg)
    }
  }
}
</script>

<style lang="less" scoped>
.el-breadcrumb {
  margin-bottom: 12px;
}
.el-card {
  .el-button {
    margin-bottom: 12px;
  }
  .el-pagination {
    margin-top: 12px;
  }
}

// 修改树形表格是否有效的图标大小
.btn-width {
  padding: 5px!important;
}
// 右外边距10像素
.margin-r {
  margin-right: 10px!important;
}

// 级联选择器宽度设置
.el-cascader {
  width: 100%;
}

// Alart调整位置
.el-alert {
  text-align: left!important;
  position: relative;
  bottom: 16px;
  left: 18px;
}

// 新增分类按钮位置调整
.dialog-footer {
  margin-top: 40px;
}

// Alart去除P标签内外边距
p {
  padding: 0;
  margin: 2px 0;
}

// 调整新增分类dialog下内边距
/deep/ .el-dialog__body {
  padding-bottom: 20px!important;
}

// /deep/操作符 有些Sass 、Less之类的预处理器无法正确解析>>>
/deep/ .zk-table tbody tr > td:first-child {
  text-align: center;
}

</style>
